<template>
    <div class="main">
        <ol>
            <li v-for="(point, index) in g_points" :key="index">
                {{ point }}
                <font color="red" style="cursor:pointer;float:right;" @click="deleted(point, index)">X</font>
            </li>
        </ol>
        <div>
            <div>
                <el-button size="small" @click="move">平移</el-button>
            </div>
            <p>
                <font color="red">gl.{{ mode }}</font>
            </p>

            <canvas id="webglCanvas" ref="webglCanvas" width="100" height="100"></canvas>
            <div>
                <el-radio-group v-model="mode" @change="draw" size="small">
                    <el-radio label="POINTS">点</el-radio>
                    <el-radio label="LINES">线段</el-radio>
                    <el-radio label="LINE_STRIP">线条</el-radio>
                    <el-radio label="LINE_LOOP">回路</el-radio>

                    <el-radio label="TRIANGLES">三角形</el-radio>
                    <el-radio label="TRIANGLE_STRIP">三角带</el-radio>
                    <el-radio label="TRIANGLE_FAN">三角扇</el-radio>
                </el-radio-group>
            </div>
        </div>
    </div>
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
const webglCanvas = ref(null);
// 顶点着色器
var VSHADER_SOURCE =
    'attribute vec4 a_Position;\n' +//定义 a_Position
    'attribute float a_PointSize;\n' +//定义 a_PointSize
    'attribute float a_Translation;\n' +//定义 偏移量
    'void main() {\n' +
    '  gl_Position = vec4(a_Position.x+a_Translation,a_Position.y+a_Translation,a_Position.z+a_Translation,1.0);\n' + // a_Position传给gl_Position
    '  gl_PointSize = a_PointSize;\n' +
    '}\n';

// 片元着色器
var FSHADER_SOURCE =
    'precision mediump float;\n' +
    'uniform vec4 u_FragColor;\n' +
    'void main() {\n' +
    '  gl_FragColor = u_FragColor;\n' + // Set the point color
    '}\n';
// 入口函数
let gl = null;
const g_points = ref([]);
const mode = ref("POINTS");
let T = 0;

// 初始化 
const init = () => {
    gl = getWebGLContext(webglCanvas.value);   //拿到webgl实例
    if (!gl) {
        console.log("fail to get the rendering context of webgl");
        return;
    }
    // 初始化着色器
    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
        console.log('Failed to intialize shaders.');
        return;
    }

    // 获取a_Position的存储位置
    const a_PointSize = gl.getAttribLocation(gl.program, "a_PointSize");
    const u_FragColor = gl.getUniformLocation(gl.program, "u_FragColor");

    // 将点的位置传到attribute变量中
    gl.vertexAttrib1f(a_PointSize, 10.0);
    gl.uniform4f(u_FragColor, 1.0, 0, 0, 1.0);

    gl.clearColor(0.0, 0.0, 0.0, 1.0);  //设置背景色
    gl.clear(gl.COLOR_BUFFER_BIT);      //清空背景

    const canvas = webglCanvas.value;
    canvas.onmousedown = function (ev: any) {
        T = 0;
        const a_Translation = gl.getAttribLocation(gl.program, "a_Translation");
        gl.vertexAttrib1f(a_Translation, T);
        let { x, y } = ev;//x、y光标在整个可视区域的坐标
        let rect = canvas.getBoundingClientRect();//用于获得页面中某个元素的左，上，右和下分别相对浏览器视窗的位置。
        let coordsX = ((x - rect.left) - canvas.width / 2) / (canvas.width / 2);
        let coordsY = (canvas.height / 2 - (y - rect.top)) / (canvas.height / 2);
        // 将坐标保存g_points
        g_points.value.push([coordsX, coordsY]);
        draw();
    }
}

// 绘制 
const draw = () => {
    // 创建类型数组
    let points = g_points.value;
    let vertices = new Float32Array(points.flat());
    // 创建缓冲区
    let vertexBuffer = gl.createBuffer();
    if (!vertexBuffer) {
        return;
    }
    // 将缓冲区绑定到目标
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    //向缓冲区写入数据
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

    const a_Position = gl.getAttribLocation(gl.program, "a_Position");
    // 将缓冲区对象分配给a_Position变量
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);

    gl.enableVertexAttribArray(a_Position);

    //清空背景
    gl.clear(gl.COLOR_BUFFER_BIT);

    // 绘制点
    gl.drawArrays(gl[mode.value], 0, points.length);
}

// 删除点
const deleted = (point, index) => {
    g_points.value.splice(index, 1);
    draw();
}

// 移动
const move = () => {
    T = T + 0.1;
    const a_Translation = gl.getAttribLocation(gl.program, "a_Translation");
    gl.vertexAttrib1f(a_Translation, T);
    draw();
}

onMounted(() => {
    init();
})
</script>

<style lang="scss">
.main {
    display: flex;
}

ol {
    float: left;
    display: block;
    width: 100px;

    li {
        text-align: left;
    }
}
</style>